package com.star.file;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;
import java.util.stream.Stream;

/**
 * Files类功能演示
 *
 * Files类是Java NIO.2 API中的核心工具类，提供了大量静态方法用于文件操作：
 * 1. 文件读写操作
 * 2. 文件属性获取
 * 3. 文件复制、移动、删除
 * 4. 目录遍历
 * 5. 文件权限管理
 *
 * 与传统的File类相比，Files类提供了更强大、更安全的文件操作功能。
 *
 * Files类的主要优势：
 * 1. 更好的异常处理：提供了IOException的精确异常信息
 * 2. 更高的性能：使用NIO.2 API，性能优于传统IO
 * 3. 更丰富的功能：支持符号链接、文件属性、权限控制等
 * 4. 更好的资源管理：自动管理文件句柄，避免资源泄露
 * 5. 支持流式操作：可以与Java 8 Stream API结合使用
 * 6. 更安全的操作：提供了原子性操作选项
 *
 * 常用方法分类：
 * 1. 读写操作：readAllBytes(), readAllLines(), write(), lines(), newBufferedReader(), newBufferedWriter()
 * 2. 属性操作：exists(), isRegularFile(), isDirectory(), size(), getLastModifiedTime()
 * 3. 管理操作：copy(), move(), delete(), createDirectory(), createDirectories()
 * 4. 遍历操作：list(), walk(), find()
 */
public class FilesTest {

    public static void main(String[] args) {
        FilesTest test = new FilesTest();

        try {
            // 演示各种Files类的功能
            test.demonstrateFilesOperations();
        } catch (IOException e) {
            System.err.println("文件操作出错: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 演示Files类的各种操作
     */
    public void demonstrateFilesOperations() throws IOException {
        System.out.println("=== Files类功能演示 ===\n");

        // 1. 文件写入操作
        demonstrateWriteOperations();

        // 2. 文件读取操作
        demonstrateReadOperations();

        // 3. 文件属性操作
        demonstrateAttributeOperations();

        // 4. 文件复制、移动、删除操作
        demonstrateFileManagementOperations();

        // 5. 目录操作
        demonstrateDirectoryOperations();
    }

    /**
     * 演示文件写入操作
     */
    private void demonstrateWriteOperations() throws IOException {
        System.out.println("1. 文件写入操作演示:");

        // 创建测试目录
        Path testDir = Paths.get("test_files");
        if (!Files.exists(testDir)) {
            Files.createDirectory(testDir);
        }

        // 方法1: write() - 写入字节数据
        Path byteFile = testDir.resolve("byte_data.txt");
        String content = "Hello, Files Class!\nThis is a test file.\n中文测试内容。";
        Files.write(byteFile, content.getBytes(StandardCharsets.UTF_8));
        System.out.println("  使用Files.write()写入字节数据完成");

        // 方法2: write() - 写入字符串列表
        Path linesFile = testDir.resolve("lines_data.txt");
        List<String> lines = List.of("第一行内容", "Second line content", "第三行内容");
        Files.write(linesFile, lines, StandardCharsets.UTF_8);
        System.out.println("  使用Files.write()写入字符串列表完成");

        System.out.println();
    }

    /**
     * 演示文件读取操作
     */
    private void demonstrateReadOperations() throws IOException {
        System.out.println("2. 文件读取操作演示:");

        Path testFile = Paths.get("test_files", "byte_data.txt");

        // 方法1: readAllBytes() - 读取所有字节
        byte[] bytes = Files.readAllBytes(testFile);
        String content = new String(bytes, StandardCharsets.UTF_8);
        System.out.println("  使用Files.readAllBytes()读取内容:");
        System.out.println("  " + content.replaceAll("\n", "\n  "));

        // 方法2: readAllLines() - 读取所有行
        List<String> lines = Files.readAllLines(testFile, StandardCharsets.UTF_8);
        System.out.println("  使用Files.readAllLines()读取行数: " + lines.size());

        // 方法3: lines() - 获取行流（Java 8+）
        try (Stream<String> linesStream = Files.lines(testFile, StandardCharsets.UTF_8)) {
            long lineCount = linesStream.count();
            System.out.println("  使用Files.lines()流式读取行数: " + lineCount);
        }

        // 方法4: newBufferedReader() - 创建缓冲读取器
        try (BufferedReader reader = Files.newBufferedReader(testFile, StandardCharsets.UTF_8)) {
            String line;
            System.out.println("  使用Files.newBufferedReader()逐行读取:");
            while ((line = reader.readLine()) != null) {
                System.out.println("  " + line);
            }
        }

        System.out.println();
    }

    /**
     * 演示文件属性操作
     */
    private void demonstrateAttributeOperations() throws IOException {
        System.out.println("3. 文件属性操作演示:");

        Path testFile = Paths.get("test_files", "byte_data.txt");

        // 基本属性
        boolean exists = Files.exists(testFile);
        boolean isRegularFile = Files.isRegularFile(testFile);
        boolean isDirectory = Files.isDirectory(testFile);
        long size = Files.size(testFile);

        System.out.println("  文件是否存在: " + exists);
        System.out.println("  是否为普通文件: " + isRegularFile);
        System.out.println("  是否为目录: " + isDirectory);
        System.out.println("  文件大小: " + size + " 字节");

        // 时间属性
        long lastModified = Files.getLastModifiedTime(testFile).toMillis();
        System.out.println("  最后修改时间: " + new java.util.Date(lastModified));

        // 权限属性
        boolean canRead = Files.isReadable(testFile);
        boolean canWrite = Files.isWritable(testFile);
        boolean canExecute = Files.isExecutable(testFile);

        System.out.println("  可读: " + canRead);
        System.out.println("  可写: " + canWrite);
        System.out.println("  可执行: " + canExecute);

        System.out.println();
    }

    /**
     * 演示文件管理操作（复制、移动、删除）
     */
    private void demonstrateFileManagementOperations() throws IOException {
        System.out.println("4. 文件管理操作演示:");

        Path sourceFile = Paths.get("test_files", "byte_data.txt");

        // 复制文件
        Path copyFile = Paths.get("test_files", "byte_data_copy.txt");
        Files.copy(sourceFile, copyFile, StandardCopyOption.REPLACE_EXISTING);
        System.out.println("  文件复制完成");

        // 移动/重命名文件
        Path movedFile = Paths.get("test_files", "byte_data_moved.txt");
        Files.move(copyFile, movedFile, StandardCopyOption.REPLACE_EXISTING);
        System.out.println("  文件移动/重命名完成");

        // 创建临时文件
        Path tempFile = Files.createTempFile("test_", ".tmp");
        Files.write(tempFile, "临时文件内容".getBytes(StandardCharsets.UTF_8));
        System.out.println("  临时文件创建完成: " + tempFile);

        // 删除文件
        Files.delete(movedFile);
        System.out.println("  文件删除成功");

        // 安全删除（如果存在）
        if (Files.exists(tempFile)) {
            Files.deleteIfExists(tempFile);
            System.out.println("  临时文件删除成功");
        }

        System.out.println();
    }

    /**
     * 演示目录操作
     */
    private void demonstrateDirectoryOperations() throws IOException {
        System.out.println("5. 目录操作演示:");

        // 创建多级目录
        Path nestedDir = Paths.get("test_files", "level1", "level2", "level3");
        Files.createDirectories(nestedDir);
        System.out.println("  多级目录创建完成");

        // 列出目录内容
        Path testDir = Paths.get("test_files");
        try (Stream<Path> paths = Files.list(testDir)) {
            System.out.println("  目录内容:");
            paths.forEach(path -> System.out.println("  " + path.getFileName()));
        }

        // 遍历目录树（递归）
        System.out.println("  目录树遍历:");
        try (Stream<Path> paths = Files.walk(testDir)) {
            paths.forEach(path -> System.out.println("  " + path));
        }

        // 查找文件（使用glob模式）
        System.out.println("  查找.txt文件:");
        try (Stream<Path> paths = Files.find(testDir, Integer.MAX_VALUE,
                (path, attrs) -> path.toString().endsWith(".txt"))) {
            paths.forEach(path -> System.out.println("  " + path));
        }

        System.out.println();
    }
}
